/*
 * Copyright (C) 2009, Edmundo Albuquerque de Souza e Silva.
 *
 * This file may be distributed under the terms of the Q Public License
 * as defined by Trolltech AS of Norway and appearing in the file
 * LICENSE.QPL included in the packaging of this file.
 *
 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

/*
 * Copyright (C) 2009, Edmundo Albuquerque de Souza e Silva.
 *
 * This file may be distributed under the terms of the Q Public License
 * as defined by Trolltech AS of Norway and appearing in the file
 * LICENSE.QPL included in the packaging of this file.
 *
 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

package net.sf.fmj.ejmf.toolkit.gui.controls.skins.ejmf;

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.UIManager;

import net.sf.fmj.ejmf.toolkit.gui.controls.GainMeter;

/** 
  * The gain meter button for StandardControlPanel.
  *
  * This class draws the default gain meter button
  * for StandardControls: A small speaker-shaped icon
  * with "waves" emanating from the front.
  * <p> 
  * A read X is drawn atop the speaker when the gain control
  * is muted. As the gain increase, more "waves" are drawn.
  * As the gain decreases, fewer "waves" are drawn.
  * <p>
  * GainMeterButton implements GainMeter in order to support
  * these operations.
  *
  * @see	net.sf.fmj.ejmf.toolkit.gui.controls.GainMeter
  */

public class GainMeterButton extends BasicControlButton 
		implements GainMeter
{
    protected int 	intLevel;
    protected boolean	muted;
	/**
	* Set gain level of gain meter.
        * The input argument is a gain level that gets
	* mapped to a number of "waves" emanating from 
	* front of speaker.
        *
	* @param level is a gain level value that 	
	* gets mapped to a display value
	*/
	
    public void setLevel(float level) {
	intLevel = mapToMeterLevel(level);
	updateView();
    }

	/**
	* Set mute state of button
	* @param muted true to draw button to reflect muted state, 
        * false otherwise.
	*/
    public void setMute(boolean muted) {
	this.muted = muted;      
	updateView();
    }

	/**
	*  Create a GainMeterButton	
	*/
    public GainMeterButton() {
	super();
    }

	/**
	*  Create a GainMeterButton with initial values.
	*/
    public GainMeterButton(float level, boolean muted) {
        setLevel(level);
	setMute(muted);
    }

    ////// Define abstract methods from AbstractGainMeterButton /////////

    /**
      * Redraws GainMeter GUI component as necessary in
      * response to change in gain value.
      */
    public void updateView() {
	repaint();
    }

    public int mapToMeterLevel(float gain) {
	int nticks = getResolution();
	int val = (int) (gain  * 10);
        int divisor = 10 / nticks;
        return val / divisor;
    }
    ////////////////////////////////////////////////

    protected void paintIcon(Graphics g, int x, int y, int size, boolean isEnabled)
    {
	int xtrans = muted ? x : x - 3;
  	g.translate(xtrans, y);

	// Speaker looks like:
	/*
                  .
                 ..
                ...
               ....
            .......
            .......
            .......
               ....
                ...
                 ..
                  .
	*/
	// ...more or less.

	int midLen = size / 2;
	int magLen = size / 5;
	// Draw magnet part of speaker
	for (int i = 0; i < size/5; i++)
	    g.drawLine(i, midLen - magLen, i, midLen + magLen); 

	// Draw cone part of speaker
	for (int i = 0; i < size; i++)
	    g.drawLine(i, midLen - i, i, midLen + i);

	// Draw 'sound waves' emanating from speaker
	//int narcs = intLevel / 2;
	int narcs = intLevel;
	if (!muted)
            for (int i = 0; i < narcs; i++)
	        g.drawArc(size, midLen - (i+1), i*2, i*2+1, 90, -180);
        
	// Draw red X
	if (muted) {
  	    g.translate(-2, -2);
	    Color oldColor = g.getColor();
	    g.setColor(Color.red);
  	    g.drawLine(0, 0, size+2, size+2);
  	    g.drawLine(0, size+2, size+2, 0);
	    g.setColor(oldColor);
  	    g.translate(2, 2);
	}
  	g.translate(-xtrans, -y);
    }

    public void paint(Graphics g) {
	Color origColor;
	boolean isPressed, isEnabled;
	int w, h, size;

        w = getSize().width;
        h = getSize().height;
	origColor = g.getColor();
	isPressed = getModel().isPressed();
	isEnabled = isEnabled();

        g.setColor(getBackground());
        g.fillRect(1, 1, w-2, h-2);

        if (isPressed) {
            g.setColor(UIManager.getColor("controlShadow"));
            g.drawRect(0, 0, w-1, h-1);
        } else {
            g.drawLine(0, 0, 0, h-1);
            g.drawLine(1, 0, w-2, 0);

            g.setColor(UIManager.getColor("controlHighlight"));    // inner 3D border
            g.drawLine(1, 1, 1, h-3);
            g.drawLine(2, 1, w-3, 1);

            g.setColor(UIManager.getColor("controlShadow"));       // inner 3D border
            g.drawLine(1, h-2, w-2, h-2);
            g.drawLine(w-2, 1, w-2, h-3);

            g.setColor(UIManager.getColor("controlDkShadow"));     // black drop shadow 
            g.drawLine(0, h-1, w-1, h-1);
            g.drawLine(w-1, h-1, w-1, 0);
        }

        if (h < 5 || w < 5)      {
            g.setColor(origColor);
            return;
        }

        if (isPressed) {
            g.translate(1, 1);
        }

        size = Math.min((h - 4) / 3, (w - 4) / 3);
        size = Math.max(size, 2);
	paintIcon(g, (w - size) / 2, (h - size) / 2,
				size, isEnabled);

        // Reset the Graphics back to it's original settings
        if (isPressed) {
            g.translate(-1, -1);
	}
	g.setColor(origColor);

    }

    protected int getResolution () {
	return 5;
    }
}
